package com.meida.common.mybatis.query;

import cn.hutool.json.JSONUtil;
import com.meida.common.constants.CommonConstants;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.SaveModel;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.FlymeUtils;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.ReflectionUtils;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * @author zyf
 */
@Data
public class CriteriaSave implements Serializable {
    private EntityMap requestMap = new EntityMap();

    private EntityMap extarMap = new EntityMap();
    /**
     * 扩展事件名称
     */
    private String handlerName;

    private Class cls;

    /**
     * 主键字段
     */
    private String idField;


    /**
     * 表名
     */
    private String tableName;

    private SaveModel model;
    /**
     * 对象是否先暂存到redis
     */
    private Boolean saveToRedis = false;


    public EntityMap getRequestMap() {
        return requestMap;
    }


    public String getHandlerName() {
        return handlerName;
    }

    public void setHandlerName(String handlerName) {
        this.handlerName = handlerName;
    }

    public CriteriaSave() {

    }

    public CriteriaSave(SaveModel model, Class cls) {
        this.cls = cls;

        this.handlerName = model.getHandlerName();
        this.model = model;
        this.tableName = ReflectionUtils.getTableName(cls);
        this.idField = ReflectionUtils.getTableField(cls);
        Long idValue = model.getId();
        String params = model.getParams();
        if (FlymeUtils.isNotEmpty(params)) {
            EntityMap entityMap = JsonUtils.jsonToBean(model.getParams(), EntityMap.class);
            if (FlymeUtils.isNotEmpty(idValue)) {
                entityMap.put(idField, idValue);
            }
            if (FlymeUtils.isNotEmpty(entityMap)) {
                this.requestMap.putAll(entityMap);
            }
        }
    }

    public CriteriaSave(Map map, Class cls) {
        this.cls = cls;
        this.handlerName = (String) map.getOrDefault(CommonConstants.HANDLER_NAME, "");
        this.setHandlerName(handlerName);
        this.tableName = ReflectionUtils.getTableName(cls);
        this.idField = ReflectionUtils.getTableField(cls);

        Object params = map.get("params");
        EntityMap test;
        if (FlymeUtils.isNotEmpty(params)) {
            //TODO 便于接口文档测试
            test = JsonUtils.jsonToBean(params.toString(), EntityMap.class);
            this.requestMap.putAll(test);
        } else {
            this.requestMap.putAll(map);
        }
    }


    public EntityMap put(String key, Object value) {
        this.requestMap.put(key, value);
        return this.requestMap;
    }

    public EntityMap setExtra(String key, Object value) {
        this.extarMap.put(key, value);
        return this.extarMap;
    }


    public <T> T getEntity(Class<T> cls) {
        T obj = JsonUtils.jsonToBean(JSONUtil.toJsonStr(requestMap), cls);
        return obj;
    }

    public <T> T getEntity() {
        Object obj = JsonUtils.jsonToBean(JSONUtil.toJsonStr(requestMap), cls);
        return (T) obj;
    }

    public <T> T getParams(String key) {
        return (T) requestMap.get(key);
    }


    public <T> T getParams(String key, String def) {
        return (T) requestMap.get(key, def);
    }

    public <T> T getExtra(String key) {
        return (T) extarMap.get(key);
    }

    public List<Long> getArrayLong(String key) {
        return requestMap.getListLong(key);
    }

    public Long getLongParams(String key) {
        return requestMap.getLong(key);
    }

    public Long getLong(String key) {
        return requestMap.getLong(key);
    }

    public <T> T getInt(String key, Integer def) {
        return (T) requestMap.getInt(key, def);
    }

    public <T> T getRequiredParams(String key) {
        T t = requestMap.get(key);
        if (FlymeUtils.isEmpty(t)) {
            ApiAssert.failure(key + "不能为空");
        }
        return t;
    }

    public EntityMap getExtarMap() {
        return extarMap;
    }

    public void setExtarMap(EntityMap extarMap) {
        this.extarMap = extarMap;
    }
}
